{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 查找三角函数\n",
    "有三种方法可以在特定角度查找一个三角函数的值。\n",
    "\n",
    "**1. 使用表格** -  这是工程师在没有使用电脑的年代查找三角函数的方式。 例如，从下面的表格可以看出 $\\sin(60)=0.866$\n",
    "\n",
    "| angle |  sin  |  cos  |  tan  |\n",
    "| :---: | :---: | :---: | :---: |\n",
    "|   0   | 0.000 | 1.000 | 0.000 |\n",
    "|  10   | 0.174 | 0.985 | 0.176 |\n",
    "|  20   | 0.342 | 0.940 | 0.364 |\n",
    "|  30   | 0.500 | 0.866 | 0.577 |\n",
    "|  40   | 0.643 | 0.766 | 0.839 |\n",
    "|  50   | 0.766 | 0.643 | 1.192 |\n",
    "|  60   | 0.866 | 0.500 | 1.732 |\n",
    "|  70   | 0.940 | 0.342 | 2.747 |\n",
    "|  80   | 0.985 | 0.174 | 5.671 |\n",
    "\n",
    "但这种技术存在的问题是，表格中总会有空白。\n",
    "\n",
    "**2. 使用图形** - 尝试填补这些空白的一种方法是查阅三角函数的曲线图。例如，下图显示了$0 \\leq \\theta \\leq 360$ 情况下的 $\\sin(\\theta)$ 曲线：\n",
    "\n",
    "![](https://d17h27t6h515a5.cloudfront.net/topher/2017/December/5a2efe68_sine/sine.png)\n",
    "\n",
    "这些图看起来很漂亮，因为它们给出了这些函数的良好视觉感，但它们对于获得准确的值并不是很好。 下面我们继续探索查找三角函数的**最佳**方法...\n",
    "\n",
    "**3. 使用电脑!** 这可能不是一个惊喜，但python已经内置了计算正弦、余弦和正切的函数。\n",
    "\n",
    " 事实上，你甚至可以在 **Google** 输入“sin（60度）”，然后就会获得正确答案！\n",
    "\n",
    "![](https://d17h27t6h515a5.cloudfront.net/topher/2017/December/5a2f0062_img-1742/img-1742.jpg)\n",
    "\n",
    "请注意我写的是”sin（60度）“，而不是“sin（60）”。 这是因为这些函数通常需要输入**弧度**。\n",
    "\n",
    "现在让我们用Python计算这些函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-0.3048106211022167\n"
     ]
    }
   ],
   "source": [
    "# Python's math module has functions called sin, cos, and tan\n",
    "# as well as the constant \"pi\" (which we will find useful shortly)\n",
    "from math import sin, cos, tan, pi\n",
    "\n",
    "# Run this cell. What do you expect the output to be?\n",
    "print(sin(60))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "输出是否符合你的预期？\n",
    "\n",
    "如果不符合，这可能是因为我们没有将角度转换为弧度。\n",
    "\n",
    "### 练习1 - 编写一个将度数转换为弧度的函数\n",
    "\n",
    "在代码中实现以下数学运算：\n",
    "\n",
    "$$\\theta_{\\text{radians}} = \\theta_{\\text{degrees}} \\times \\frac{\\pi}{180}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "ename": "AssertionError",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAssertionError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-2-209c50b41772>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      5\u001b[0m     \u001b[0;31m#    code at end of notebook)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0;32massert\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdeg2rad\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m45.0\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mpi\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      8\u001b[0m \u001b[0;32massert\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdeg2rad\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m90.0\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mpi\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      9\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Nice work! Your degrees to radians function works!\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mAssertionError\u001b[0m: "
     ]
    }
   ],
   "source": [
    "from math import pi\n",
    "def deg2rad(theta):\n",
    "    \"\"\"Converts degrees to radians\"\"\"\n",
    "    # TODO - implement this function (solution\n",
    "    #    code at end of notebook)\n",
    "\n",
    "assert(deg2rad(45.0) == pi / 4)\n",
    "assert(deg2rad(90.0) == pi / 2)\n",
    "print(\"Nice work! Your degrees to radians function works!\")\n",
    "\n",
    "for theta in [0, 30, 45, 60, 90]:\n",
    "    theta_rad = deg2rad(theta)\n",
    "    sin_theta = sin(theta_rad)\n",
    "    print(\"sin(\", theta, \"degrees) =\", sin_theta)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 练习2 - 绘制余弦与正切曲线图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "def plot_sine(min_theta, max_theta):\n",
    "    \"\"\"\n",
    "    Generates a plot of sin(theta) between min_theta\n",
    "    and max_theta (both of which are specified in degrees).\n",
    "    \"\"\"\n",
    "    angles_degrees = np.linspace(min_theta, max_theta)\n",
    "    angles_radians = deg2rad(angles_degrees)\n",
    "    values = np.sin(angles_radians)\n",
    "    X = angles_degrees\n",
    "    Y = values\n",
    "    plt.plot(X,Y)\n",
    "    plt.show()\n",
    "    \n",
    "# EXERCISE 2.1 Implement this! Try not to look at the\n",
    "#  implementation of plot_sine TOO much...\n",
    "def plot_cosine(min_theta, max_theta):\n",
    "    \"\"\"\n",
    "    Generates a plot of sin(theta) between min_theta\n",
    "    and max_theta (both of which are specified in degrees).\n",
    "    \"\"\"\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_sine(0, 360)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_cosine(0, 360)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#\n",
    "\n",
    "#\n",
    "\n",
    "#\n",
    "\n",
    "#\n",
    "\n",
    "# SOLUTION CODE\n",
    "\n",
    "#\n",
    "\n",
    "#\n",
    "\n",
    "#\n",
    "\n",
    "#\n",
    "from math import pi\n",
    "def deg2rad_solution(theta):\n",
    "    \"\"\"Converts degrees to radians\"\"\"\n",
    "    return theta * pi / 180\n",
    "\n",
    "assert(deg2rad_solution(45.0) == pi / 4)\n",
    "assert(deg2rad_solution(90.0) == pi / 2)\n",
    "\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "def plot_cosine_solution(min_theta, max_theta):\n",
    "    \"\"\"\n",
    "    Generates a plot of sin(theta) between min_theta\n",
    "    and max_theta (both of which are specified in degrees).\n",
    "    \"\"\"\n",
    "    angles_degrees = np.linspace(min_theta, max_theta)\n",
    "    angles_radians = deg2rad_solution(angles_degrees)\n",
    "    values = np.cos(angles_radians)\n",
    "    X = angles_degrees\n",
    "    Y = values\n",
    "    plt.plot(X,Y)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_cosine_solution(0, 360)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
